#define GLEW_STATIC

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <Shader.h>
#include <iostream>

using namespace std;

// vertices data
float gVertices[] =
{
   0.5f, 0.5f, 0.0f,
   -0.5f, 0.5f, 0.0f,
   0.0f,  0.5f - 0.5f * sqrtf(3.0f), 0.0f,
};

int main()
{
   // -------------- WINDOW --------------

   glfwInit();
   glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
   glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
   glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

   GLFWwindow* window = glfwCreateWindow(500, 500, "Homework1", nullptr, nullptr);

   if (window == nullptr)
   {
      glfwTerminate();
      cout << "GLFW Error" << endl;
      return EXIT_FAILURE;
   }
   glfwMakeContextCurrent(window);

   // -------------- Render --------------

   glewExperimental = true;

   if (glewInit() != GLEW_OK)
   {
      glfwTerminate();
      cout << "GLEW Error" << endl;
      return EXIT_FAILURE;
   }
   
   glViewport(0, 0, 500, 500);

   // Create VAO
   unsigned int VAO;
   glCreateVertexArrays(1, &VAO);

   // Create VBO
   unsigned int VBO;
   glCreateBuffers(1, &VBO);

   // bind VAO VBO
   glBindVertexArray(VAO);
   glBindBuffer(GL_ARRAY_BUFFER, VBO);

   // send data
   glBufferData(GL_ARRAY_BUFFER, sizeof(gVertices), gVertices, GL_STATIC_DRAW);

   // Making Shader
   Shader shader("shader.vert", "shader.frag");

   // set VAO vertex attribute pointer
   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
   glEnableVertexAttribArray(0);

   // set uniform
   float offsetValue = 0.2f;
   shader.Use();
   shader.SetUniform("rOffset", offsetValue);

   // rendering iteration
   while (!glfwWindowShouldClose(window))
   {
      // set bgcolor
      glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
      glClear(GL_COLOR_BUFFER_BIT);
      
      // bind VAO VBO
      glBindVertexArray(VAO);
      glBindBuffer(GL_ARRAY_BUFFER, VBO);

      // set shader
      shader.Use();

      // render
      glDrawArrays(GL_TRIANGLES, 0, 3);
      glfwSwapBuffers(window);
      glfwPollEvents();
   }

   glfwTerminate();

   return EXIT_SUCCESS;
}